home *** CD-ROM | disk | FTP | other *** search
- // Copyright 1994 by Jon Dart. All Rights Reserved.
-
- #include "display.h"
- #include "square.h"
- #include "constant.h"
- #include <wpwin.h>
- #include <string.h>
- #include <stdio.h>
-
- static WPBitmap *pawn_bitmap = NULL;
- static WPBitmap *pawn_outline = NULL;
- static WPBitmap *knight_bitmap = NULL;
- static WPBitmap *knight_outline = NULL;
- static WPBitmap *bishop_bitmap = NULL;
- static WPBitmap *bishop_outline = NULL;
- static WPBitmap *rook_bitmap = NULL;
- static WPBitmap *rook_outline = NULL;
- static WPBitmap *queen_bitmap = NULL;
- static WPBitmap *queen_outline = NULL;
- static WPBitmap *king_bitmap = NULL;
- static WPBitmap *king_outline = NULL;
-
- #define DARK_SQUARE_COLOR RGB(0,0x80,0)
- #define LIGHT_SQUARE_COLOR RGB(0,0xFF,0)
- #define STATUS_AREA_WIDTH 80
- #define TEXT_OFFSET 75 /* from right edge */
- #define TIME_Y 80
- #define MOVE_Y 170
- #define PLY_Y 210
-
- int Display::spacing = 0;
-
- Display::Display( WPWin *pWin, const WPRect &initial_size )
- : turned(False)
- {
- TEXTMETRIC my_tm;
- WPWinDC dc = pWin;
- GetTextMetrics(dc(),&my_tm);
- char_width = my_tm.tmAveCharWidth;
- max_char_width = my_tm.tmMaxCharWidth;
- char_height = my_tm.tmHeight;
- spacing = my_tm.tmHeight + my_tm.tmExternalLeading;
- vertical_border_width = char_width + 6;
- horiz_border_height = char_height + 4;
-
- set_size((WPRect)initial_size);
- if (pawn_bitmap)
- return;
- pawn_bitmap = new WPBitmap("PAWN_BITMAP");
- pawn_outline = new WPBitmap("PAWN_OUTLINE");
- knight_bitmap = new WPBitmap("KNIGHT_BITMAP");
- knight_outline = new WPBitmap("KNIGHT_OUTLINE");
- bishop_bitmap = new WPBitmap("BISHOP_BITMAP");
- bishop_outline = new WPBitmap("BISHOP_OUTLINE");
- rook_bitmap = new WPBitmap("ROOK_BITMAP");
- rook_outline = new WPBitmap("ROOK_OUTLINE");
- queen_bitmap = new WPBitmap("QUEEN_BITMAP");
- queen_outline = new WPBitmap("QUEEN_OUTLINE");
- king_bitmap = new WPBitmap("KING_BITMAP");
- king_outline = new WPBitmap("KING_OUTLINE");
-
- }
-
- Display::~Display()
- {
- delete king_bitmap;
- delete king_outline;
- delete queen_bitmap;
- delete queen_outline;
- delete rook_bitmap;
- delete rook_outline;
- delete bishop_bitmap;
- delete bishop_outline;
- delete knight_bitmap;
- delete knight_outline;
- delete pawn_bitmap;
- delete pawn_outline;
- }
-
- void Display::draw_piece(WPDevContext &dc,
- WPRect &square,WPBitmap *bitmap,WPRect &src_rect,
- const ColorType color,WPBitmap *outline)
- {
- // make dest square a little smaller, to avoid clobbering
- // black space between squares:
- WPRect new_area(square.left()+1,square.top()+1,
- square.right()-1,square.bottom()-1);
- if (color == Black)
- {
- WPMemDC memdc(&dc, bitmap);
- dc.stretchBlt(new_area,memdc,src_rect,MERGECOPY);
- }
- else
- {
- {
- WPMemDC memdc(&dc, bitmap);
- dc.stretchBlt(new_area,memdc,src_rect,MERGEPAINT);
- }
- if (outline)
- {
- WPMemDC memdc(&dc,outline);
- dc.stretchBlt(new_area,memdc,src_rect,SRCAND);
- }
- }
- }
-
- void Display::draw_piece( WPDevContext &dc, WPRect &square, const Piece &piece)
- {
- WPRect src_rect(1,1,62,62);
- switch(piece.Type())
- {
- case Piece::Pawn:
- {
- draw_piece(dc,square,pawn_bitmap,src_rect,piece.Color(),
- pawn_outline);
- break;
- }
- case Piece::Rook:
- {
- draw_piece(dc,square,rook_bitmap,src_rect,piece.Color(),
- rook_outline);
- break;
- }
- case Piece::Knight:
- {
- draw_piece(dc,square,knight_bitmap,src_rect,piece.Color(),
- knight_outline);
- break;
- }
- case Piece::Bishop:
- {
- draw_piece(dc,square,bishop_bitmap,src_rect,piece.Color(),
- bishop_outline);
- break;
- }
- case Piece::Queen:
- {
- draw_piece(dc,square,queen_bitmap,src_rect,piece.Color(),
- queen_outline);
- break;
- }
- case Piece::King:
- {
- draw_piece(dc,square,king_bitmap,src_rect,piece.Color(),
- king_outline);
- break;
- }
- default:
- break;
- }
- }
-
- void Display::set_size(WPRect &size)
- {
- display_area = size;
- width = size.width();
- height = size.height() - horiz_border_height;
- square_height = height/8;
- square_width = (width - STATUS_AREA_WIDTH - vertical_border_width) / 8;
- }
-
- void Display::draw_board( WPDevContext &dc, const Board &board,
- const WPRect *drawArea)
- {
- HRGN drawRegion = CreateRectRgnIndirect((RECT *)drawArea);
- int vert_incr, vert_start, horiz_incr, horiz_start;
- if (turned)
- {
- vert_incr = -square_height;
- vert_start = 7*square_height;
- horiz_incr = -square_width;
- horiz_start = 7*square_width;
- }
- else
- {
- vert_incr = square_height;
- vert_start = horiz_start = 0;
- horiz_incr = square_width;
- }
- int vert = vert_start;
- int horiz;
- const int right_edge = square_width*8;
- const int bottom_edge = square_height*8;
- HRGN paintRegion = CreateRectRgn(0,0,0,0);
- int mono = dc.getCap(NUMCOLORS) <= 2;
- for (int i = 0; i < 8; i++)
- {
- horiz = horiz_start;
-
- // draw text in vertical border:
- int text_start = (i*square_height) + square_height/2 - char_height/2;
- RECT rc;
- SetRect(&rc,right_edge+3, text_start,
- right_edge+vertical_border_width-3,
- text_start+max_char_width);
- char border_text[1];
- *border_text = (turned) ? '1' + i : '8' - i;
- DrawText(dc(),border_text,1,&rc,DT_LEFT);
-
- // draw text in horizontal border:
- text_start = (i*square_width) + square_width/2 - char_width/2;
- SetRect(&rc, text_start,bottom_edge+2,text_start+max_char_width,
- bottom_edge+horiz_border_height);
- *border_text = (turned) ? 'H' - i : 'A' + i;
- DrawText(dc(),border_text,1,&rc,DT_LEFT);
-
- for (int j = 0; j < 8; j++)
- {
- Square sq(j+1,i+1,Black);
- WPRect square(WPPoint(horiz,vert),
- WPPoint(horiz+square_width,vert+square_height));
- HRGN squareRegion = CreateRectRgnIndirect((RECT*)&square);
- if (CombineRgn(paintRegion,squareRegion,drawRegion,RGN_AND)
- != NULLREGION)
- {
- if ((j + i) % 2)
- {
- if (mono)
- dc.setBrushHatch(COLOR_BLACK,HS_DIAGCROSS);
- else
- dc.setBrush(DARK_SQUARE_COLOR);
- }
- else
- {
- if (mono)
- dc.setBrush(COLOR_WHITE);
- else
- dc.setBrush(LIGHT_SQUARE_COLOR);
- }
- dc.rectangle(square);
- Piece piece(board[sq]);
- if (!piece.IsEmpty())
- {
- draw_piece(dc,square,piece);
- }
- }
- horiz += horiz_incr;
- DeleteObject(squareRegion);
- }
- vert += vert_incr;
-
- }
- show_side(dc,board.Side());
- DeleteObject(paintRegion);
- DeleteObject(drawRegion);
- }
-
- void Display::square_rect(const Square &sq, WPRect &out )
- {
- WPRect size = get_size();
- int rank = sq.Rank(Black);
- int file = sq.File();
- if (turned)
- {
- rank = 9-rank;
- file = 9-file;
- }
- WPPoint orig(square_width*(file-1),square_height*(rank-1));
- WPPoint end(square_width*file,square_height*rank);
- out = WPRect(orig,end);
- }
-
- void Display::draw_piece( WPDevContext &dc, const Square &loc, const Piece &p )
- {
- WPRect area;
- square_rect(loc,area);
- draw_piece(dc,area,p);
- }
-
- void Display::draw_square( WPDevContext &dc, const Square &loc )
- {
- WPRect area;
- square_rect(loc,area);
- int mono = dc.getCap(NUMCOLORS) <= 2;
- if ((loc.Rank(Black) + loc.File()) % 2)
- {
- if (mono)
- dc.setBrushHatch(COLOR_BLACK,HS_DIAGCROSS);
- else
- dc.setBrush(DARK_SQUARE_COLOR);
- }
- else
- {
- if (mono)
- dc.setBrush(COLOR_WHITE);
- else
- dc.setBrush(LIGHT_SQUARE_COLOR);
- }
- dc.rectangle(area);
- }
-
- void Display::highlight_square( WPDevContext &, const Square & )
- {
- // unimplemented
- }
-
- void Display::unhighlight_square( WPDevContext &, const Square & )
- {
- // unimplemented
- }
-
- void Display::set_turned(Boolean turnit)
- {
- turned = turnit;
- }
-
- Square Display::mouse_loc( WPPoint &p)
- {
- int x,y;
- x = (p.x/square_width)+1;
- if (turned)
- x = 9-x;
- y = (p.y/square_height)+1;
- if (x > 8 || y > 8)
- return Square(0);
- else
- return Square(x,y,turned ? White : Black);
- }
-
- void Display::show_side( WPDevContext &dc, const ColorType side )
- {
- static char *wstr = "WHITE to move";
- static char *bstr = "BLACK to move";
- RECT rcText;
- int start = width - TEXT_OFFSET;
- SetRect(&rcText,start,20,width-5,80);
- DrawText(dc(),(side == White) ? wstr : bstr,
- lstrlen(wstr), &rcText, DT_LEFT | DT_WORDBREAK);
- }
-
- void Display::show_move( WPDevContext &dc, const char *move_image,
- int number )
- {
- RECT rcText;
- int start = width - TEXT_OFFSET;
- SetRect(&rcText,start,MOVE_Y,start+width-5,
- MOVE_Y+spacing);
- char text[80];
- // erase any previous text:
- HBRUSH brush = GetStockObject(WHITE_BRUSH);
- FillRect(dc(),&rcText,brush);
- int move_num = (number-1)/2;
- if (number % 2)
- wsprintf(text,"%d %s",move_num+1,move_image);
- else
- wsprintf(text,"%d ... %s",move_num+1,move_image);
- DrawText(dc(),text,strlen(text), &rcText, DT_LEFT | DT_WORDBREAK);
- }
-
- void Display::clear_move_area( WPDevContext &dc)
- {
- RECT rcText;
- int start = width - TEXT_OFFSET;
- SetRect(&rcText,start,MOVE_Y,start+width-5,
- MOVE_Y+spacing);
- // erase any previous text:
- HBRUSH brush = GetStockObject(WHITE_BRUSH);
- FillRect(dc(),&rcText,brush);
- }
-
- void Display::clear_status_line( WPDevContext &dc )
- {
- RECT rcText;
- int start = width - TEXT_OFFSET;
- SetRect(&rcText,start,MOVE_Y+spacing,width-5,
- MOVE_Y+2*spacing);
- HBRUSH brush = GetStockObject(WHITE_BRUSH);
- // erase any previous contents of this field:
- FillRect(dc(),&rcText,brush);
- }
-
- void Display::show_status( WPDevContext &dc, const Search::Statistics stats)
- {
- static char *images[] =
- {
- " ",
- " ",
- "Check! ",
- "Mate! ",
- "Stalemate",
- "Draw! ",
- "I resign!"
- };
- RECT rcText;
- int start = width - TEXT_OFFSET;
- SetRect(&rcText,start,MOVE_Y+spacing,width-5,
- MOVE_Y+2*spacing);
- HBRUSH brush = GetStockObject(WHITE_BRUSH);
- // erase any previous contents of this field:
- FillRect(dc(),&rcText,brush);
- char text[30];
- if ((stats.state == Search::Normal || stats.state == Search::Check) &&
- (stats.value > Constants::BIG-100))
- {
- if (stats.value == Constants::BIG-1)
- strcpy(text,"Checkmate!");
- else
- wsprintf(text,"Mate in %d!",(Constants::BIG-stats.value-1)/2);
- }
- else
- wsprintf(text,"%s",images[stats.state]);
- DrawText(dc(),text,strlen(text), &rcText, DT_LEFT | DT_WORDBREAK);
- }
-
- void Display::show_time( HWND handle, const time_t time,
- const ColorType side )
- {
- // all straight Windows code - because we have no access to
- // Windows++ classes
-
- HDC hdc = GetDC(handle);
- assert(hdc);
- char time_str[20];
- unsigned hours = time/3600L;
- unsigned minutes = (time - (hours*3600L))/60L;
- unsigned seconds = (time - (hours*3600L) - (minutes*60L));
- // convert time to ASCII:
- wsprintf(time_str,"%02d:%02d:%02d",
- (int)hours,(int)minutes,(int)seconds);
- RECT rcText, client_rect, text_rect;
- GetClientRect( handle, &client_rect );
- int width = client_rect.right - client_rect.left;
- int vbase = TIME_Y;
- TEXTMETRIC tm;
- if (side == White)
- {
- SetRect(&text_rect,width-TEXT_OFFSET,vbase,width-5,vbase+spacing);
- DrawText(hdc,"WHITE:",6,&text_rect,DT_LEFT);
- SetRect(&rcText,width-TEXT_OFFSET,vbase+spacing,width-5,vbase+2*spacing);
- }
- else
- {
- SetRect(&text_rect,width-TEXT_OFFSET,vbase+2*spacing,width-5,
- vbase+3*spacing);
- DrawText(hdc,"BLACK:",6,&text_rect,DT_LEFT);
- SetRect(&rcText,width-TEXT_OFFSET,vbase+3*spacing,width-5,vbase+4*spacing);
- }
- DrawText(hdc,time_str,lstrlen(time_str),&rcText,
- DT_LEFT | DT_WORDBREAK);
- BOOL ret = ReleaseDC(handle,hdc);
- assert(ret);
- }
-
- void Display::clear_search_counts( WPDevContext &dc )
- {
- RECT rcText;
- int start = width - TEXT_OFFSET;
- SetRect(&rcText,start,PLY_Y,width-5,
- PLY_Y+4*spacing);
- HBRUSH brush = GetStockObject(WHITE_BRUSH);
- // erase any previous contents of this field:
- FillRect(dc(),&rcText,brush);
- }
-
- void Display::show_search_counts( HWND handle, const int ply,
- const long nodes)
- {
- RECT rcText, client_rect, text_rect;
- GetClientRect( handle, &client_rect );
- int width = client_rect.right - client_rect.left;
- int vbase = PLY_Y;
- HDC hdc = GetDC(handle);
- assert(hdc);
- SetRect(&text_rect,width-TEXT_OFFSET,vbase,width-5,vbase+spacing);
- char msg[20];
- wsprintf(msg,"Ply: %d",ply);
- DrawText(hdc,msg,lstrlen(msg),&text_rect,
- DT_LEFT | DT_WORDBREAK);
- text_rect.top += spacing;
- text_rect.bottom += spacing;
- DrawText(hdc,"Nodes:",6,&text_rect,
- DT_LEFT | DT_WORDBREAK);
- text_rect.top += spacing;
- text_rect.bottom += spacing;
- wsprintf(msg,"%ld",nodes);
- DrawText(hdc,msg,lstrlen(msg),&text_rect,
- DT_LEFT | DT_WORDBREAK);
- BOOL ret = ReleaseDC(handle,hdc);
- assert(ret);
- }
-